import {routerRedux} from 'dva/router';
import {setToken, removeToken} from '../utils/authority';
import {reloadAuthorized} from '../utils/Authorized';
import {query as queryUsers, getUserInfo, fakeRegister, fakeAccountLogin, fakeLogout} from '../services/user';
import {setStore, getStore, setAuthority} from "../utils/store";
import {getAuthMenus, getRouterData} from '../services/api';

export default {
  namespace: 'user',

  state: {
    status: undefined,
    list: [],
    currentUser: getStore({
      name: 'userInfo',
    }) || {},
    permissions: getStore({
      name: 'permissions',
    }) || {},
    roles: getStore({
      name: 'roles',
    }) || [],
    access_token: getStore({
      name: 'access_token',
    }) || '',
    refresh_token: getStore({
      name: 'refresh_token',
    }) || '',
    // 存储菜单数据(全局缓存)
    menus: [],
    // 存储路由数据(全局缓存)
    routerData: [],
  },

  effects: {
    * submit({payload}, {call, put}) {
      const response = yield call(fakeRegister, payload);
      yield put({
        type: 'registerHandle',
        payload: response,
      });
    },
    * fetchMenus(_, {call, put, select}) { // 增加
      const menus = yield call(getAuthMenus);
      console.log(menus)
      if (menus) {
        const routerConfig = yield select(state => state.user.routerConfig);
        const routerData = yield call(getRouterData, routerConfig, menus);
        yield put({
          type: 'saveMenus',
          payload: menus,
        });

        yield put({
          type: 'saveRouterData',
          payload: routerData,
        });
      } else {
        yield put(routerRedux.push('/user/login'));
      }
    },
    * login({payload}, {call, put}) {

      const response = yield call(fakeAccountLogin, {...payload, grant_type: 'password', scope: 'server'});

      if (response) {
        response.type = payload.type

        if (!("error" in response)) {
          response.status = 'ok'
        } else {
          response.status = 'error'
        }

        yield put({
          type: 'changeLoginStatus',
          payload: response,
        });

        if (response.status === 'ok') {
          setToken(response.access_token)
          yield put({
            type: 'setAccessTokenAndRefreshToken',
            payload: response,
          });

          const usesRes = yield call(getUserInfo);

          console.log(usesRes.data)

          yield put({
            type: 'saveCurrentUser',
            payload: usesRes.data,
          });

          reloadAuthorized();
          yield put(routerRedux.push('/dashboard/analysis'));
        }
      }
    },
    * logout({payload}, {call, put, select}) {

      const response = yield call(fakeLogout, payload)

      if (response.code === 0) {
        yield put({type: 'logOutClear',});
        yield put({
          type: 'saveMenus',
          payload: [],
        });
        try {
          // get location pathname
          const urlParams = new URL(window.location.href);
          const pathname = yield select(state => state.routing.location.pathname);
          // add the parameters in the url
          urlParams.searchParams.set('redirect', pathname);
          window.history.replaceState(null, 'login', urlParams.href);
        } finally {
          yield put({
            type: 'changeLoginStatus',
            payload: {
              status: false,
            },
          });
          reloadAuthorized();
          yield put(routerRedux.push('/user/login'));
        }
      }


    },
    * fetch(_, {call, put}) {
      const response = yield call(queryUsers);
      yield put({
        type: 'save',
        payload: response,
      });
    },
    * fetchCurrent(_, {call, put}) {
      const response = yield call(getUserInfo);

      console.log(response.data)

      yield put({
        type: 'saveCurrentUser',
        payload: response.data,
      });
    },
  },

  reducers: {
    saveMenus(state, {payload}) {
      return {
        ...state,
        menus: payload,
      };
    },
    saveRouterConfig(state, {payload}) {
      return {
        ...state,
        routerConfig: payload,
      };
    },
    saveRouterData(state, {payload}) {
      return {
        ...state,
        routerData: payload,
      };
    },
    changeLoginStatus(state, {payload}) {
      setStore({
        name: 'access_token',
        content: payload.access_token,
        type: 'session',
      })
      return {
        ...state,
        status: payload.status,
        type: payload.type,
      };
    },
    setAccessTokenAndRefreshToken(state, {payload}) {
      setStore({
        name: 'access_token',
        content: payload.access_token,
        type: 'session',
      })
      setStore({
        name: 'refresh_token',
        content: payload.refresh_token,
        type: 'session',
      })
      return {
        ...state,
        refresh_token: payload.refresh_token,
        access_token: payload.access_token,
      }
    },
    logOutClear(state) {
      setStore({
        name: 'access_token',
        content: '',
        type: 'session',
      })
      setStore({
        name: 'refresh_token',
        content: '',
        type: 'session',
      })
      setStore({
        name: 'roles',
        content: [],
        type: 'session',
      })
      setStore({
        name: 'permissions',
        content: [],
        type: 'session',
      })
      setStore({
        name: 'userInfo',
        content: {},
        type: 'session',
      })
      removeToken()
      setAuthority('')
      return {
        ...state,
        currentUser: {},
        permissions: {},
        roles: [],
        access_token: '',
        refresh_token: '',
      }
    },

    save(state, action) {
      return {
        ...state,
        list: action.payload,
      };
    },
    saveCurrentUser(state, action) {
      setStore({
        name: 'userInfo',
        content: action.payload.sysUser,
        type: 'session',
      })

      setAuthority(action.payload.roles)
      setStore({
        name: 'roles',
        content: action.payload.roles,
        type: 'session',
      })
      const list = {}
      for (let i = 0; i < action.payload.permissions.length; i++) {
        list[action.payload.permissions[i]] = true
      }
      setStore({
        name: 'permissions',
        content: list,
        type: 'session',
      })

      return {
        ...state,
        currentUser: action.payload.sysUser,
        roles: action.payload.roles,
        permissions: list,
      };
    },
    changeNotifyCount(state, action) {
      return {
        ...state,
        currentUser: {
          ...state.currentUser,
          notifyCount: action.payload,
        },
      };
    },
    registerHandle(state, {payload}) {
      reloadAuthorized();
      return {
        ...state,
        status: payload.status,
      };
    },
  }
};
